<template>
  <div>
    <el-progress v-show="showEl" :percentage="percentage" :color="customColorMethod" />
    <div
      v-loading="loading"
      class="app-container"
      :element-loading-text="text"
      element-loading-spinner="el-icon-loading"
      element-loading-background="rgba(255, 255, 255, 0.8)"
    >
      <div class="filter-container">
        <el-divider />
        <el-select
          v-model="tableName"
          placeholder="请选择表"
          @change="onTableChange"
        >
          <el-option
            v-for="item in tableOptions"
            :key="item.name"
            :label="item.name"
            :value="item.name"
          />
        </el-select>
        后端算法
        <el-select v-model="algorithmValue" placeholder="请选择后端处理算法">
          <el-option
            v-for="item in algorithmOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        前端算法
        <el-select v-model="algorithmTwoValue" placeholder="请选择前端处理算法" @change="onAlgorithmTwo">
          <el-option
            v-for="item in algorithmTwoOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <br>
        精确调整开始时间
        <el-input-number v-model="startTime" controls-position="right" :min="fixedStartTime" :max="fixedEndTime" />
        精确调整结束时间
        <el-input-number v-model="endTime" controls-position="right" :min="fixedStartTime" :max="fixedEndTime" />
        <el-select v-model="queryDataVolume" clearable placeholder="快速选择查询数" @change="onChangeQueryData">
          <el-option
            v-for="item in queryDataVolumes"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-button v-waves class="filter-item" type="primary" :disabled="disabled" icon="el-icon-search" @click="handleFilter">
          查询
        </el-button>
        <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="downloadFile">
          下载
        </el-button>
        <el-slider v-model="tableTimes" style="width:80%" range :min="fixedStartTime" :max="fixedEndTime" :format-tooltip="formatTooltip" @change="onSliderChange" />
        <div id="MyEcharts" :class="className" :style="{height:height,width:width}" />
      </div>

    </div>
  </div>
</template>

<script>

import moment from 'moment'
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import { chartList, tableList } from '@/api/chart'
import waves from '@/directive/waves' // waves directive
import store from '@/store'

let optionDataOne = null
// let progressFlag = true
export default {
  directives: { waves },
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '650px'
      // default: '100%'
    }
  },
  data: function() {
    return {
      disabled: true,
      percentage: 0,
      showEl: true,
      xkk: true,
      currentTableName: '',
      loading: false,
      text: '加载中...(0%)',
      startTime: 0,
      endTime: 1,
      fixedStartTime: 0,
      fixedEndTime: 1,
      chart: null,
      timeQuery: [],
      algorithmOptions: [{
        value: 'MaximumValue',
        label: '最大值'
      }, {
        value: 'MinimumValue',
        label: '最小值'
      }, {
        value: 'AverageValue',
        label: '平均值'
      }],
      algorithmValue: 'AverageValue',
      algorithmTwoOptions: [{
        value: 'max',
        label: '最大值'
      }, {
        value: 'min',
        label: '最小值'
      }, {
        value: 'average',
        label: '平均值'
      }, {
        value: 'sum',
        label: '和'
      }, {
        value: 'lttb',
        label: 'LTTB'
      }],
      algorithmTwoValue: 'LTTB',
      queryDataVolumes: [{
        value: 500000000,
        label: '500M(5亿)'
      }, {
        value: 50000000,
        label: '50M(5千万)'
      }, {
        value: 10000000,
        label: '10M(一千万)'
      }, {
        value: 100000,
        label: '100K(十万)'
      }, {
        value: 1000,
        label: '1K(一千)'
      }],
      queryDataVolume: null,
      displayTheorySpot: '1000',
      dataLoadInfo: {},
      tableOptions: [],
      tableName: '',
      tableTimes: [],
      listQuery: {
        name: null,
        type: null,
        startTime: null,
        endTime: null
      },
      option: {
        toolbox: {
          show: true,
          feature: {
            dataZoom: {
              yAxisIndex: 'none'
            },
            magicType: { type: ['line', 'bar'] },
            saveAsImage: {}
          },
          right: '10%'
        },
        axisPointer: {
          snap: false
        },
        tooltip: {
          // show : false,
          trigger: 'axis',
          triggerOn: 'mousemove',
          confine: true,
          transitionDuration: 0.25,
          backgroundColor: 'rgba(50,50,50,0.7)',
          axisPointer: {
            snap: false
          // }
          },
          formatter: function(params) {
            let xString = params[0].value.ts
            xString = xString.replace('T', ' ')
            const h = Number(xString.substring(11, 13)) + 8
            const yer = xString.substring(0, 11)
            const min = xString.substring(13, 19)
            const newXString = yer + h + min
            const yValue = params[0].value.value
            let stringValue = '<span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#1bf55f\"></span>' + newXString + '</span>' + '<br>&nbsp&nbsp&nbsp&nbsp' + yValue + '<br><br>'

            const dataIndex = params[0].dataIndex
            const data = optionDataOne.source
            if (data.length === 1) {
              return stringValue
            }
            let beforeData = null
            let afterData = null
            const beforeString = '<span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#c23531\"></span>与前节点差值<br>' + '&nbsp&nbsp&nbsp&nbsp'
            const afterString = '<span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#e2a909\"></span>与后节点差值<br>' + '&nbsp&nbsp&nbsp&nbsp'
            if (dataIndex === 0) {
              afterData = data[dataIndex + 1]
              const afterNumber = ((Number(yValue) - Number(afterData.value))).toFixed(8)
              stringValue = stringValue + afterString + afterNumber
            } else if (dataIndex === data.length - 1) {
              beforeData = data[dataIndex - 1]
              const beforeNumber = (Number(yValue) - Number(beforeData.value)).toFixed(8)
              stringValue = stringValue + beforeString + beforeNumber
            } else {
              beforeData = data[dataIndex - 1]
              afterData = data[dataIndex + 1]
              const beforeNumber = (Number(yValue) - Number(beforeData.value)).toFixed(8)
              stringValue = stringValue + beforeString + beforeNumber + '<br><br>'
              const afterNumber = (Number(yValue) - Number(afterData.value)).toFixed(8)
              stringValue = stringValue + afterString + afterNumber
            }
            return stringValue
          }
        },
        grid: [
          {
            bottom: '20%'
          }, {
            top: '85%',
            tooltip: {
              show: true
            }
          }
        ],
        xAxis: [
          {
            type: 'time',
            gridIndex: 0,
            axisPointer: {
              snap: false
            }
          },
          {
            type: 'time',
            gridIndex: 1
          }
        ],
        yAxis: [
          {
            type: 'value',
            gridIndex: 0,
            scale: true
          },
          {
            type: 'value',
            gridIndex: 1,
            scale: true,
            show: false
          }
        ],
        dataZoom: [
          {
            type: 'slider',
            show: true,
            // realtime: false,
            xAxisIndex: 0,
            // yAxisIndex: 0,
            start: 15,
            end: 85
          },
          {
            type: 'inside',
            realtime: true,
            xAxisIndex: 0,
            // yAxisIndex: 0,
            start: 15,
            end: 85,
            zoomOnMouseWheel: true,
            moveOnMouseMove: true
            // moveOnMouseWheel: true
          }
        ],
        dataset: [
          {
            source: []
          },
          {
            source: []
          }
        ],
        series: [
          {
            type: 'line',
            datasetIndex: 0,
            symbol: 'none',
            sampling: 'lttb',
            encode: {
              'x': 'ts',
              'y': 'value'
            },
            markArea: {
              silent: true,
              itemStyle: {
                color: 'rgba(16,220,255,0.4)'
              }
            },
            xAxisIndex: 1,
            yAxisIndex: 1
          },
          {
            type: 'line',
            datasetIndex: 1,
            sampling: 'lttb',
            symbol: 'none',
            encode: {
              'x': 'ts',
              'y': 'value'
            },
            xAxisIndex: 0,
            yAxisIndex: 0
          }
        ]
      },
      timer: ''
    }
  },
  // 页面初始化的时候
  mounted() {
    // 从状态记录器里 获取 表信息
    this.$data.dataLoadInfo = this.$store.getters.dataLoadInfo
    // 执行页面数据初始化
    // this.$nextTick(() => {
    this.initChart()
    // })
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    // 快速选择触发
    onChangeQueryData(value) {
      const common = this
      if ((common.startTime + value) > common.fixedEndTime) {
        common.startTime = (common.fixedEndTime - value)
        common.endTime = common.fixedEndTime
      } else {
        common.endTime = (common.startTime + value)
      }
      common.tableTimes = [common.startTime, common.endTime]
    },
    // 拖动后触发
    onSliderChange(value) {
      this.startTime = value[0]
      this.endTime = value[1]
    },
    // 文件下载
    downloadFile() {
      const common = this
      const aTag = document.createElement('a')
      aTag.href = 'http://localhost:8080/chart/downloadFile?id=' + common.dataLoadInfo.id + '&startTime=' + common.startTime + '&endTime=' + common.endTime
      aTag.click()
    },
    // 滑动条显示效果的方法
    formatTooltip(value) {
      return moment(new Date(parseInt(value))).format('YYYY年MM月DD日 HH时mm分ss秒SSS毫秒')
      // return value
    },
    // 初始化图 对 总体趋势进行赋值,
    initEcharts() {
      const common = this
      // 开启遮罩
      this.loading = true
      // 设置查询条件
      common.listQuery.name = common.tableName
      common.listQuery.type = common.algorithmValue
      common.listQuery.startTime = common.startTime
      common.listQuery.endTime = common.endTime
      common.listQuery.windowRatio = 10
      // common.handleFilter()
      chartList(common.listQuery).then(response => {
        const option = common.option
        option.dataset[0] = {
          source: response.data.items
        }
        common.handleFilter()
      })
    },
    // 图标初始化 和查询
    handleFilter() {
      this.showProgress(80)
      const common = this
      common.queryDataVolume = null

      // 开启遮罩
      this.loading = true
      common.listQuery.name = common.tableName
      common.listQuery.type = common.algorithmValue
      common.listQuery.startTime = common.startTime
      common.listQuery.endTime = common.endTime
      common.listQuery.windowRatio = 1
      chartList(this.listQuery).then(response => {
        const option = common.option
        // console.log(option.dataset)
        // console.log(option.dataset[0])
        // option.dataset[0] = {
        //   source: response.data.items
        // }

        option.dataset[1] = {
          source: response.data.items
        }
        option.series[0].markArea.data = [
          [
            {
              xAxis: common.startTime
            },
            {
              xAxis: common.endTime
            }
          ]
        ]

        // 将查询出来数据赋值给全局变量，用于计算两个数据点间的数据差值并且在tooltip中显示
        optionDataOne = { source: response.data.items }

        // 折线图点击事件 common.chart.getZr().on('click',function(params){}
        /*
        common.chart.off('click')
        common.chart.on('click', function (params) {
          let dataIndex = params.dataIndex
          let data = optionDataOne.source
          let beforeData = null
          let afterData = null
          if (dataIndex == 0) {
            afterData = data[dataIndex+1]
          }else if (dataIndex == data.length-1) {
            beforeData = data[dataIndex-1]
          }else {
            beforeData = data[dataIndex-1]
            afterData = data[dataIndex+1]
          }
          console.log(option.dataset[1])
          console.log(dataIndex)
          console.log(params)
        })
        */

        common.chart.setOption(option)
        // console.log( option)
        // 收到结果关闭遮罩
        common.loading = false
        // 进度条加载完成
        this.percentage = 100

        clearInterval(this.timer)

        this.hiddenProgress(1500)
      })
    },
    initChart() {
      const common = this
      // 获取 echarts 对象
      common.chart = echarts.init(this.$el.querySelector('#MyEcharts'), 'macarons')
      tableList().then(response => {
        common.tableOptions = response.data.items
        if (this.dataLoadInfo == null) {
          common.dataLoadInfo = common.tableOptions[0]
        }
        common.currentTableName = common.tableName
        // 获取表名
        common.tableName = common.dataLoadInfo.name
        // 获取开始时间
        common.startTime = parseInt(common.dataLoadInfo.startTime)
        // 获取结束时间
        common.endTime = parseInt(common.dataLoadInfo.endTime)
        common.tableTimes[0] = common.startTime
        common.tableTimes[1] = common.endTime
        common.fixedStartTime = common.startTime
        common.fixedEndTime = common.endTime
        common.chart.on('datazoom', common.onMousewheel)
        common.initEcharts()
      })
    },
    onMousewheel(params) {
      const common = this
      if (common.xkk) {
        common.xkk = false
        let start
        // let dataLoading = false
        let end
        // 拿到了 开始百分比和结束和结束百分比
        if (params.batch === undefined) {
          start = params.start
          end = params.end
        } else {
          start = params.batch[0].start
          end = params.batch[0].end
        }
        // console.log("start: ", start)
        // console.log("end: ", end)
        // 当 当前放缩doa小于10 和大于 90 的时候准备判断是否进行数据加载
        let b
        if ((end - start) < 10) {
          // console.log("ok: ")
          common.dataLoading = true
          b = true
        }
        if ((end - start) > 90) {
          common.dataLoading = true
          b = false
        }
        // 当 start 与 end 为null 标识是toolbox触发
        if (start === undefined && end === undefined) {
          const startTime = parseInt(params.batch[0].startValue)
          const endTime = parseInt(params.batch[0].endValue)
          // console.log("start: ", countStartTime)
          // console.log("end: ", countEndTime)
          common.startTime = startTime
          common.endTime = endTime
          common.tableTimes = [common.startTime, common.endTime]
          common.handleFilter()
        }
        // 初步判断需要数据加载
        if (common.dataLoading) {
          common.dataLoading = false
          // 获取 最大值 最小值  当前开始 与当前结束
          const fixedStartTime = common.fixedStartTime
          const fixedEndTime = common.fixedEndTime
          const startTime = parseInt(common.startTime)
          const endTime = parseInt(common.endTime)
          // 准备 需要计算的 开始与结束值
          let countStartTime
          let countEndTime
          if (b) {
            // 判断缩小
            const number = endTime - startTime
            if (number > 5000) {
              // 当前区间大于5000的时候,进行加载更加详细的图
              const numberTrunc = parseInt(number / 100)
              const startTrunc = parseInt(start)
              const endTrunc = parseInt(end)
              countStartTime = parseInt(startTime + (startTrunc * numberTrunc))
              countEndTime = parseInt(startTime + (endTrunc * numberTrunc))
              // console.log("start: ", countStartTime)
              // console.log("end: ", countEndTime)
              common.startTime = countStartTime
              common.endTime = countEndTime
              common.tableTimes = [common.startTime, common.endTime]
              common.handleFilter()
            }
          } else {
            // 判断放大
            // 当已经是最大范围的时候 不进行操作
            if (startTime === fixedStartTime && fixedEndTime === endTime) {
              return
            }
            const number = endTime - startTime
            // console.log("number: ", number)
            const numberTrunc = parseInt(number * 10)
            // console.log("numberTrunc: ", numberTrunc)
            const number1 = parseInt(startTime - numberTrunc)
            const number2 = parseInt(endTime + numberTrunc)
            // console.log("number1: ", number1)
            // console.log("number2: ", number2)
            countStartTime = number1 < fixedStartTime ? fixedStartTime : number1
            countEndTime = number2 > fixedEndTime ? fixedEndTime : number2
            // console.log("start: ", countStartTime)
            // console.log("end: ", countEndTime)
            common.startTime = countStartTime
            common.endTime = countEndTime
            common.tableTimes = [common.startTime, common.endTime]
            common.handleFilter()
          }
        }
        common.xkk = true
      } else {
        // console.log("多次触发被拦截: ")
      }
    },
    onTableChange(value) {
      const common = this
      const tableOptions = common.tableOptions
      for (const table of tableOptions) {
        if (table.name === value) {
          store.dispatch('data/setDataLoadInfo', table)
          common.$data.dataLoadInfo = table
          common.currentTableName = common.$data.dataLoadInfo.name
        }
      }
      // 获取开始时间
      common.startTime = parseInt(common.dataLoadInfo.startTime)
      // 获取结束时间
      common.endTime = parseInt(common.dataLoadInfo.endTime)
      common.fixedStartTime = common.startTime
      common.fixedEndTime = common.endTime
      common.tableTimes[0] = common.startTime
      common.tableTimes[1] = common.endTime
    },
    onAlgorithmTwo(value) {
      const common = this
      common.option.series[0].sampling = value
      common.option.series[1].sampling = value
      common.chart.setOption(common.option, true)
      console.log(echarts.version)
    },
    customColorMethod(percentage) {
      if (percentage < 30) {
        return '#909399'
      } else if (percentage < 70) {
        return '#e6a23c'
      } else {
        return '#67c23a'
      }
    },
    increase() {
      const number = Math.floor(Math.random() * (3) + 1)
      const newPercentage = this.percentage + number
      if (newPercentage < 100) {
        this.text = '加载中...(' + newPercentage + '%)'
        this.percentage = newPercentage
      }
    },
    async showProgress(ms) {
      this.showEl = true
      this.percentage = 0
      // progressFlag = true
      // while (progressFlag) {
      //   await new Promise((res) => {
      //     setTimeout(() => { res() }, ms)
      //   })
      // }
      clearInterval(this.timer)
      this.timer = setInterval(this.increase, ms)
    },
    async hiddenProgress(ms) {
      this.disabled = true
      await new Promise((res) => {
        setTimeout(() => { res() }, ms)
      })
      // 隐藏进度条
      this.showEl = false
      this.disabled = false
    }
  }
}
</script>

